활성화 함수(Activation Function)란?
활성화 함수는 신경망의 각 뉴런에서 입력 신호의 가중합을 받아 최종 출력을 결정하는 비선형 함수이다. 활성화 함수가 없으면 다층 신경망도 결국 선형 변환의 합성일 뿐이므로, 비선형 문제를 해결할 수 없다.
주요 활성화 함수의 종류
1. 시그모이드(Sigmoid) 함수
시그모이드 함수는 가장 전통적인 활성화 함수 중 하나로, 다음과 같이 정의된다:
In [6]:
# 시그모이드 함수 그래프
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 1000)
y = 1 / (1 + np.exp(-x))
plt.figure(figsize=(8, 5))
plt.plot(x, y, 'b-', linewidth=2)
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.8)
plt.axvline(x=0, color='k', linestyle='-', linewidth=0.8)
plt.xlabel('x')
plt.ylabel('σ(x)')
plt.title('Sigmoid Function')
plt.grid(True, alpha=0.3)
plt.xlim(-10, 10)
plt.ylim(-0.1, 1.1)
plt.show()특징:
- 출력 범위: 0과 1 사이의 값을 출력한다
- 미분 가능: 모든 구간에서 미분 가능하며, 도함수가 간단한 형태로 표현된다
- 도함수:
- 용도: 이진 분류 문제의 출력층에서 자주 사용된다
장점:
- 출력을 확률로 해석하기 좋다
- 부드러운 곡선으로 안정적인 기울기를 제공한다
단점:
- 기울기 소멸 문제가 심각하다
- 중심이 0이 아니어서 학습이 비효율적일 수 있다
- 지수 함수 계산이 비용이 크다
기울기 소멸 문제란 깊은 신경망의 역전파 과정에서 기울기가 0에 가까워져 학습이 거의 이루어지지 않는 현상을 말한다.
원인:
- 시그모이드 함수의 도함수 는 최대값이 0.25이며, 대부분의 구간에서 매우 작다
- 깊은 신경망에서 각 층마다 작은 도함수를 곱하게 되므로, 층이 깊어질수록 기울기가 기하급수적으로 작아진다 (예: )
영향:
- 초기 층의 학습 부재, 학습 속도 저하, 로컬 미니멈에 빠짐
해결책:
- 깊은 신경망에서는 시그모이드 함수 대신 ReLU 계열의 활성화 함수를 사용한다
2. 하이퍼볼릭 탄젠트(Tanh) 함수
Tanh 함수는 시그모이드 함수를 변형한 것으로, 다음과 같이 정의된다:
특징:
- 출력 범위: -1과 1 사이의 값을 출력한다
- 도함수:
- 용도: 은닉층에서 시그모이드 대신 사용되기도 한다
장점:
- 출력이 0 중심이어서 시그모이드보다 학습이 효율적이다
- 시그모이드보다 기울기 소멸 문제가 덜 심각하다
단점:
- 여전히 기울기 소멸 문제가 있다
- 지수 함수 계산이 필요하다
In [17]:
# 하이퍼볼릭 탄젠트 함수 그래프
x = np.linspace(-10, 10, 1000)
y = np.tanh(x)
plt.figure(figsize=(8, 5))
plt.plot(x, y, 'b-', linewidth=2)
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.8)
plt.axvline(x=0, color='k', linestyle='-', linewidth=0.8)
plt.xlabel('x')
plt.ylabel('tanh(x)')
plt.title('Tanh Function')
plt.grid(True, alpha=0.3)
plt.xlim(-10, 10)
plt.ylim(-1.2, 1.2)
plt.show()3. ReLU (Rectified Linear Unit) 함수
ReLU 함수는 현재 가장 널리 사용되는 활성화 함수로, 다음과 같이 정의된다:
특징:
- 출력 범위: 0 이상의 값을 출력한다
- 도함수:
- 용도: 은닉층에서 주로 사용된다
장점:
- 계산이 매우 빠르다 (단순한 max 연산)
- 기울기 소멸 문제가 거의 없다 (양수 영역에서 기울기가 1)
- 희소성(sparsity)을 유도하여 효율적인 표현을 만든다
단점:
- Dying ReLU 문제: 음수 입력에서 기울기가 0이 되어 뉴런이 죽을 수 있다
- 출력이 0 중심이 아니다
In [14]:
# ReLU 함수 그래프
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 1000)
y = np.maximum(0, x)
plt.figure(figsize=(8, 5))
plt.plot(x, y, 'b-', linewidth=2)
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.8)
plt.axvline(x=0, color='k', linestyle='-', linewidth=0.8)
plt.xlabel('x')
plt.ylabel('ReLU(x)')
plt.title('ReLU Function: max(0, x)')
plt.grid(True, alpha=0.3)
plt.xlim(-10, 10)
plt.ylim(-2, 10)
plt.show()4. Leaky ReLU 함수
Leaky ReLU는 Dying ReLU 문제를 해결하기 위해 제안된 함수이다:
특징:
- 음수 영역에서도 작은 기울기(보통 0.01)를 가진다
- Dying ReLU 문제를 완화한다
장점:
- ReLU의 장점을 유지하면서 Dying ReLU 문제를 해결한다
- 계산이 빠르다
단점:
- 하이퍼파라미터(음수 영역의 기울기)를 조정해야 한다
In [19]:
# Leaky ReLU 함수 그래프
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 1000)
y = np.maximum(0.05 * x, x)
plt.figure(figsize=(8, 5))
plt.plot(x, y, 'b-', linewidth=2)
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.8)
plt.axvline(x=0, color='k', linestyle='-', linewidth=0.8)
plt.xlabel('x')
plt.ylabel('Leaky ReLU(x)')
plt.title('Leaky ReLU Function')
plt.grid(True, alpha=0.3)
plt.xlim(-10, 10)
plt.ylim(-2, 10)
plt.show()5. ELU (Exponential Linear Unit) 함수
ELU는 ReLU의 변형으로, 다음과 같이 정의된다:
특징:
- 음수 영역에서 부드러운 곡선을 가진다
- 출력이 0 중심에 가깝다
장점:
- Dying ReLU 문제를 해결한다
- ReLU보다 일반적으로 더 나은 성능을 보인다
단점:
- 지수 함수 계산이 필요하여 ReLU보다 느리다
In [7]:
# ELU 함수 그래프
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 1000)
alpha = 1.0
y = np.where(x > 0, x, alpha * (np.exp(x) - 1))
plt.figure(figsize=(8, 5))
plt.plot(x, y, 'b-', linewidth=2)
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.8)
plt.axvline(x=0, color='k', linestyle='-', linewidth=0.8)
plt.xlabel('x')
plt.ylabel('ELU(x)')
plt.title('ELU Function: x if x > 0, else α(e^x - 1)')
plt.grid(True, alpha=0.3)
plt.xlim(-10, 10)
plt.ylim(-2, 10)
plt.show()